package com.kx.center.service.impl;

import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.kx.center.common.Cache;
import com.kx.center.common.Constant;
import com.kx.center.entity.Account;
import com.kx.center.entity.Company;
import com.kx.center.exception.AccountAlreadyExistsException;
import com.kx.center.mappers.AccountMapper;
import com.kx.center.service.AccountService;
import com.kx.center.util.SHA1Coder;
import com.kx.center.util.SQLUtil;
import com.kx.center.util.Salts;
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;

@Service
public class AccountServiceImpl implements AccountService {

    @Autowired
	private AccountMapper mapper;
    
	@SuppressWarnings("restriction")
	@Override
	public void createAccount(Account account) throws GeneralSecurityException, AccountAlreadyExistsException {

		if(this.mapper.findAccountByLoginName(account.getLoginName()) != null){
			throw new AccountAlreadyExistsException();
		}
		
		// 使用Salt进行加密
		byte[] salt = Salts.nextSalt();
		char[] plaintext = account.getPassword().toCharArray();
		byte[] ciphertext = SHA1Coder.encrypt(plaintext, salt);

		account.setSalt(Base64.encode(salt));
		account.setPassword(Base64.encode(ciphertext));
		
		mapper.insertAccount(account);
		
		Cache.set(Cache.ACCOUNT, account.getId(), account);
	}

	@Override
	public void updateAccount(Account account) {
		mapper.updateAccount(account);
	}

	@Override
	public Account findAccountById(Integer id) {
		Account account = (Account) Cache.get(Cache.ACCOUNT, id);
		if(account != null)
			return account;
		return mapper.findAccountById(id);
	}

	@Override
	public Account findAccountByLoginName(String loginName) {
		Account account = (Account) Cache.get(Cache.ACCOUNT, loginName);
		if(account != null)
			return account;
		return mapper.findAccountByLoginName(loginName);
	}

	@Override
	public Account findAccountByLoginNameAndPassword(String loginName, String password)
			throws GeneralSecurityException {
		Account account = findAccountByLoginName(loginName);
		
		if(account == null) {
			return null;
		}

		byte[] salt = Base64.decode(account.getSalt());
		char[] plaintext = password.trim().toCharArray();
		byte[] ciphertext = SHA1Coder.encrypt(plaintext, salt);

		if(account.getPassword().equals(Base64.encode(ciphertext))){
			String token = UUID.randomUUID().toString().replaceAll("-", "");
			account.setToken(token);
			
			Cache.set(Cache.TOKEN, token, (long)(System.currentTimeMillis()/1000 + Constant.TOKEN_VAILDITY));
			Cache.set(Cache.ACCOUNT, token, account);
			
			updateAccount(account);
			return account;
		} else {
			return null;
		}
	}

	@Override
	public List<Account> findAccountByDepartmentId(Integer departmentId) {
		return mapper.findAccountByDepartmentId(departmentId);
	}

	@Override
	public List<Account> findAccountByCompany(int pageNum, int count, Map<String, Object> whereMap) {
		
		String order = "account_id desc";
		String limitStr = pageNum * count +","+(count+1);
		
		String where = "";
		where = SQLUtil.builWhere(whereMap);
		List<Account> companyAccountList = mapper.findCompanyAccountList(where, order, limitStr);
		
		if(companyAccountList == null){
			companyAccountList = new ArrayList<Account>();
		}
		
		return companyAccountList;
		
	}

	@Override
	public Account findAccountByToken(String token) {
		Map<String, Object> whereMap = new HashMap<String,Object>();
		whereMap.put("token", token);
		whereMap.put("status", 1);
		String where = SQLUtil.builWhere(whereMap);
		List<Account> accountList = mapper.findCompanyAccountList(where , "account_id","1");
		if(accountList != null && accountList.size() > 0){
			return accountList.get(0);
		}
		return null;
	}

}
